home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / util / pack / xpk_Source.lha / xpk_Source / xpkmaster / xpkmaster.c < prev    next >
C/C++ Source or Header  |  1996-12-07  |  18KB  |  690 lines

  1. #ifndef XPKMASTER_XPKMASTER_C
  2. #define XPKMASTER_XPKMASTER_C
  3.  
  4. /* Routinesheader
  5.  
  6.     Name:        xpkmaster.c
  7.     Main:        xpkmaster
  8.     Versionstring:    $VER: xpkmaster.c 1.0 (09.10.96)
  9.     Author:        SDI
  10.     Distribution:    PD
  11.     Description:    the main xpk functions
  12.  
  13.  1.0   09.10.96 : first real version
  14. */
  15.  
  16. #include <pragma/exec_lib.h>
  17. #include <pragma/intuition_lib.h>
  18. #include <pragma/dos_lib.h>
  19. #include <exec/types.h>
  20. #include <exec/memory.h>
  21. #include <exec/tasks.h>
  22. #include <libraries/ppbase.h>
  23. #include <dos/dos.h>
  24. #include "xpkmaster.h"
  25. #include "xpk_strings.h"
  26.  
  27. /**************************************************************************
  28.  *
  29.  *   XpkPack() - pack a file
  30.  *
  31.  */
  32.  
  33. #ifdef __cplusplus
  34.   extern "C"
  35. #endif
  36.  
  37. LONG __asm XpkPack(register __a0 struct TagItem *tags A4PROTO)
  38. {
  39.  
  40.   struct XpkBuffer *xbuf = NULL;
  41.   STRPTR buf;
  42.   LONG totlen, chunklen, res;
  43.  
  44. #if defined(DEBUG) && defined(SUPPORT_A4)
  45.   DebugRunTime("XpkPack: A4 = %ld", a4);
  46. #endif
  47.  
  48.   if(findtag(tags, XPK_PackMethod) == -1)
  49.     return XPKERR_BADPARAMS;
  50.  
  51.   if((res = XpkOpen(&xbuf, tags A4SUPP)))
  52.     return res;
  53.  
  54.   totlen = xbuf->xb_InLen;
  55.  
  56.   /* Start the clock     */
  57.   CurrentTime (&xbuf->xb_Secs, &xbuf->xb_Mics);
  58.  
  59.   xbuf->xb_Prog.xp_Type = XPKPROG_START;
  60.   xbuf->xb_Prog.xp_ULen = totlen;
  61.   if(callprogress(xbuf))
  62.     goto Abort;
  63.  
  64.   while(totlen > 0)
  65.   {
  66.     chunklen = xbuf->xb_Fib.xf_NLen;
  67.     if(!(buf = (STRPTR) hookread (xbuf, XIO_READ, NULL, chunklen)))
  68.       goto Abort;
  69.  
  70.     if(XpkWrite(xbuf, buf, chunklen))
  71.       goto Abort;
  72.  
  73.     totlen -= chunklen;
  74.  
  75.     xbuf->xb_Prog.xp_Type = XPKPROG_MID;    /* Progress report     */
  76.     xbuf->xb_Prog.xp_UCur += chunklen;
  77.     xbuf->xb_Prog.xp_CCur = xbuf->xb_Fib.xf_CCur;
  78.     if(callprogress (xbuf))
  79.       goto Abort;
  80.   }
  81.  
  82. /* Abort: Here or below? CvR */
  83.   if (xbuf->xb_Prog.xp_Type) {
  84.     xbuf->xb_Prog.xp_Type = XPKPROG_END;
  85.     xbuf->xb_Prog.xp_CCur += xbuf->xb_Headers.h_LocSize;
  86.     xbuf->xb_Prog.xp_Activity = xbuf->xb_Result ?
  87.       strings[TXT_ABORTED] : xbuf->xb_LastMsg;
  88.     callprogress(xbuf);     /* Call the hook one last time */
  89.   }
  90. Abort:
  91.   return XpkClose(xbuf);
  92. }
  93.  
  94. /*********************************************************************
  95.  *
  96.  * XpkUnpack - unpack a file
  97.  *
  98.  */
  99.  
  100. #ifdef __cplusplus
  101.   extern "C"
  102. #endif
  103.  
  104. LONG __asm XpkUnpack(register __a0 struct TagItem *tags A4PROTO)
  105. {
  106.   struct XpkBuffer *xbuf = NULL;
  107.   STRPTR pointer;
  108.   LONG len, res;
  109.  
  110. #if defined(DEBUG) && defined(SUPPORT_A4)
  111.   DebugRunTime("XpkUnpack: A4 = %ld", a4);
  112. #endif
  113.  
  114.   if((res = XpkOpen(&xbuf, tags A4SUPP)))
  115.     return res;
  116.  
  117. #ifdef DEBUG
  118.   if(xbuf->xb_Result)
  119.     DebugError("XpkUnpack: XpkOpen failed?");
  120. #endif
  121.  
  122.   if(xbuf->xb_Flags & XMF_PACKING)
  123.   {
  124.     xbuf->xb_Result = XPKERR_BADPARAMS;
  125.     goto Abort;
  126.   }
  127.  
  128.   /* Start the clock     */
  129.   CurrentTime (&xbuf->xb_Secs, &xbuf->xb_Mics);
  130.  
  131.   xbuf->xb_Prog.xp_Type = XPKPROG_START;    /* Initialize progress */
  132.   xbuf->xb_Prog.xp_ULen = xbuf->xb_ULen;
  133.   if(callprogress(xbuf))
  134.     goto Abort;
  135.  
  136.   if(!hookwrite(xbuf, XIO_TOTSIZE, NULL, xbuf->xb_Fib.xf_ULen + XPK_MARGIN))
  137.   {
  138. #ifdef DEBUG
  139.     DebugError("XpkUnpack: XIO_TOTSIZE failed");
  140. #endif
  141.     goto Abort;
  142.   }
  143.  
  144. #ifdef DEBUG
  145.   DebugRunTime("XpkUnpack:after hookwrite.XIO_TOTSIZE, %ld, %ld, %ld",
  146.   xbuf->xb_WMsg.xmm_BufOfs, xbuf->xb_WMsg.xmm_Size,
  147.   xbuf->xb_WMsg.xmm_BufLen);
  148. #endif
  149.  
  150.   if(!(pointer = (STRPTR) hookwrite(xbuf, XIO_GETBUF, 0,
  151.   xbuf->xb_Fib.xf_NLen)))
  152.   {
  153. #ifdef DEBUG
  154.     DebugError("XpkUnpack: XIO_GETBUF failed (a)");
  155. #endif
  156.     goto Abort;
  157.   }
  158.  
  159. #ifdef DEBUG
  160.   DebugRunTime("XpkUnpack:after hookwrite.XIO_GETBUF, %ld, %ld, %ld, %ld, %ld, %ld",
  161.   xbuf->xb_WMsg.xmm_BufOfs, xbuf->xb_WMsg.xmm_Size, xbuf->xb_WMsg.xmm_BufLen, xbuf->xb_Fib.xf_CCur,
  162.   xbuf->xb_Fib.xf_UCur, xbuf->xb_Fib.xf_NLen);
  163. #endif
  164.  
  165. #ifdef DEBUG
  166.   if(xbuf->xb_Result)
  167.     DebugError("XpkUnpack: failure before unpackloop");
  168. #endif
  169.  
  170.   while((len = XpkRead(xbuf, pointer, XPKLEN_ONECHUNK)) > 0)
  171.   {
  172. #ifdef DEBUG
  173.   DebugRunTime("XpkUnpack:in unpack loop - before hookwrite XIO_WRITE, %ld, %ld, %ld, %ld, %ld, %ld, %ld",
  174.   xbuf->xb_WMsg.xmm_BufOfs, xbuf->xb_WMsg.xmm_Size, xbuf->xb_WMsg.xmm_BufLen, xbuf->xb_Fib.xf_CCur,
  175.   xbuf->xb_Fib.xf_UCur, xbuf->xb_Fib.xf_NLen, len);
  176. #endif
  177.     if(!hookwrite(xbuf, XIO_WRITE, pointer, len))
  178.     {
  179. #ifdef DEBUG
  180.       DebugError("XpkUnpack: XIO_WRITE failed");
  181. #endif
  182.       goto Abort;
  183.     }
  184.  
  185. #ifdef DEBUG
  186.   DebugRunTime("XpkUnpack:in unpack loop - after hookwrite.XIO_WRITE, %ld, %ld, %ld, %ld, %ld, %ld",
  187.   xbuf->xb_WMsg.xmm_BufOfs, xbuf->xb_WMsg.xmm_Size, xbuf->xb_WMsg.xmm_BufLen, xbuf->xb_Fib.xf_CCur,
  188.   xbuf->xb_Fib.xf_UCur, xbuf->xb_Fib.xf_NLen);
  189. #endif
  190.  
  191.     xbuf->xb_Prog.xp_Type = XPKPROG_MID;    /* Progress report     */
  192.     xbuf->xb_Prog.xp_CCur = xbuf->xb_Fib.xf_CCur;
  193.     xbuf->xb_Prog.xp_UCur = xbuf->xb_Fib.xf_UCur;
  194.     if(callprogress(xbuf))
  195.       goto Abort;
  196.  
  197.     if(!(pointer = (STRPTR) hookwrite(xbuf, XIO_GETBUF, NULL, xbuf->xb_Fib.xf_NLen)))
  198.     {
  199. #ifdef DEBUG
  200.       DebugError("XpkUnpack: XIO_GETBUF failed (b)");
  201. #endif
  202.       goto Abort;
  203.     }
  204.   }
  205.  
  206. #ifdef DEBUG
  207.   DebugRunTime("XpkUnpack:after hookwrite.XIO_GETBUF 2nd time, %ld, %ld, %ld",
  208.   xbuf->xb_WMsg.xmm_BufOfs, xbuf->xb_WMsg.xmm_Size, xbuf->xb_WMsg.xmm_BufLen);
  209. #endif
  210.  
  211.   xbuf->xb_Result = len;
  212. #ifdef DEBUG
  213.   if(xbuf->xb_Result)
  214.     DebugError("XpkUnpack: XpkRead failed with %ld", xbuf->xb_Result);
  215. #endif
  216.  
  217. /* Abort: Here or below? CvR */
  218.   if (xbuf->xb_Prog.xp_Type)
  219.   {
  220.     xbuf->xb_Prog.xp_Type = XPKPROG_END;
  221.     xbuf->xb_Prog.xp_Activity = xbuf->xb_Result ? strings[TXT_ABORTED] : xbuf->xb_LastMsg;
  222.     callprogress (xbuf);    /* Call the hook one last time */
  223.   }
  224. Abort:
  225.   return XpkClose (xbuf);
  226. }
  227.  
  228. /*********************************************************************
  229.  *
  230.  * XpkOpen - open a file for packing/unpacking
  231.  *
  232.  */
  233.  
  234. #ifdef __cplusplus
  235.   extern "C"
  236. #endif
  237.  
  238. LONG __asm XpkOpen (register __a0 struct XpkBuffer **xbufp,
  239.     register __a1 struct TagItem *tags A4PROTO)
  240. {
  241. #if defined(DEBUG) && defined(SUPPORT_A4)
  242.   DebugRunTime("XpkOpen: A4 = %ld", a4);
  243. #elif defined(DEBUG)
  244.   DebugRunTime("XpkOpen");
  245. #endif
  246.   return xpkopen(xbufp, tags, 0 A4SUPP);
  247. }
  248.  
  249. /**************************************************************************
  250.  *
  251.  *   XpkExamine() - inspect a compressed file
  252.  *
  253.  */
  254.  
  255. #ifdef __cplusplus
  256.   extern "C"
  257. #endif
  258.  
  259. LONG __asm XpkExamine(register __a0 struct XpkFib *fib,
  260.     register __a1 struct TagItem *tags A4PROTO)
  261. {
  262.   struct XpkBuffer *dummy;
  263.   LONG res;
  264.  
  265. #if defined(DEBUG) && defined(SUPPORT_A4)
  266.   DebugRunTime("XpkExamine: A4 = %ld", a4);
  267. #elif defined(DEBUG)
  268.   DebugRunTime("XpkExamine");
  269. #endif
  270.  
  271.   if((res = xpkopen(&dummy, tags, 1 A4SUPP)))
  272.     return res;
  273.  
  274.   CopyMem(dummy, fib, sizeof(struct XpkFib));
  275.   // copies the entries of XpkFib
  276.   // *fib = dummy->Fib works too, but calls it's own copy-function
  277.  
  278.   return XpkClose(dummy);
  279. }
  280.  
  281. /**************************************************************************
  282.  *
  283.  *   XpkRead() - read one chunk from a compressed file
  284.  *
  285.  */
  286.  
  287. #ifdef __cplusplus
  288.   extern "C"
  289. #endif
  290.  
  291. LONG __asm XpkRead(register __a0 struct XpkBuffer *xbuf,
  292.     register __a1 STRPTR buf, register __d0 ULONG len)
  293. {
  294.   struct XpkSubParams *xpar;
  295.   struct Library *XpkSubBase = xbuf->xb_SubBase;
  296.   XpkChunkHeader *lochdr = &(xbuf->xb_Headers.h_Loc);
  297.   LONG ulen, clen, rclen, lochdrsize = xbuf->xb_Headers.h_LocSize;
  298.   ULONG csum;
  299.   ULONG maxon_bug; // remove later all assigns to this var - only workaround
  300.            // for MaxonC++ bug
  301.  
  302. #ifdef DEBUG
  303.   DebugRunTime("XpkRead");
  304. #endif
  305.  
  306.   if(!xbuf)
  307.     return XPKERR_NOFUNC;
  308.  
  309.   if(xbuf->xb_Flags & XMF_EOF)
  310.     return 0;
  311.  
  312.   switch(xbuf->xb_Format) 
  313.   {
  314.     /*********************** Unpack standard XPK *******************/
  315.   case XPKMODE_UPSTD:
  316.     if(lochdr->xch_Word.xchw_Type == XPKCHUNK_END)
  317.       return 0;
  318.  
  319. // remove (maxon_bug = ..) later, when Maxon removed the bug!
  320.     if((maxon_bug = hchecksum((STRPTR) lochdr, lochdrsize)))
  321.     {
  322. #ifdef DEBUG
  323.       DebugError("XpkRead: hchecksum(,%ld) failed", lochdrsize);
  324. #endif
  325.       return(xbuf->xb_Result = XPKERR_CHECKSUM);
  326.     }
  327.  
  328.     if(xbuf->xb_Headers.h_Glob.xsh_Flags & XPKSTREAMF_LONGHEADERS)
  329.       ulen = lochdr->xch_Long.xchl_ULen, clen = lochdr->xch_Long.xchl_CLen;
  330.     else
  331.       ulen = lochdr->xch_Word.xchw_ULen, clen = lochdr->xch_Word.xchw_CLen;
  332.     rclen = ROUNDLONG(clen);
  333.  
  334.     if(lochdr->xch_Word.xchw_Type == XPKCHUNK_RAW)
  335.     {
  336. // remove later assignment
  337.       if(!(maxon_bug = (ULONG) hookread(xbuf, XIO_READ, buf, rclen + lochdrsize)))
  338.     return xbuf->xb_Result;
  339.  
  340.       if(!(xbuf->xb_Flags & XMF_NOCRC))
  341.     if((csum=cchecksum ((ULONG *) buf, rclen >>2 )) != lochdr->xch_Word.xchw_CChk)
  342.     {
  343. #ifdef DEBUG
  344.       DebugError("XpkRead: cchecksum(,%ld) = %lx != %lx failed", rclen >> 2, csum, (ULONG) lochdr->xch_Word.xchw_CChk);
  345. #endif
  346.       return (xbuf->xb_Result = XPKERR_CHECKSUM);
  347.         }
  348.  
  349.       CopyMem(buf + rclen, lochdr, lochdrsize);
  350.     }
  351.     else if(lochdr->xch_Word.xchw_Type == XPKCHUNK_PACKED)
  352.     {
  353.       xpar = &xbuf->xb_PackParam;
  354.       if(!(xpar->xsp_InBuf = hookread(xbuf, XIO_READ, NULL, rclen + lochdrsize)))
  355.     return xbuf->xb_Result;
  356.  
  357.       if(!(xbuf->xb_Flags & XMF_NOCRC))
  358.     if((csum=cchecksum ((ULONG *)xpar->xsp_InBuf, rclen >> 2)) != lochdr->xch_Word.xchw_CChk)
  359.     {
  360. #ifdef DEBUG
  361.       DebugError("XpkRead: cchecksum(,%ld) = %lx != %lx failed", rclen >>2 , csum, (ULONG) lochdr->xch_Word.xchw_CChk);
  362. #endif
  363.       return (xbuf->xb_Result = XPKERR_CHECKSUM);
  364.         }
  365.       xbuf->xb_Flags |= XMF_INITED;
  366.  
  367.       xpar->xsp_InLen = clen;
  368.       xpar->xsp_OutLen = ulen;
  369.       xpar->xsp_OutBufLen = ulen;
  370.       xpar->xsp_Number = 0;
  371.       xpar->xsp_OutBuf = buf;
  372.       xpar->xsp_Password = xbuf->xb_Password;
  373.       xpar->xsp_LibVersion = xbuf->xb_Headers.h_Glob.xsh_SubVrs;
  374.  
  375.       if((xbuf->xb_Result = XpksUnpackChunk(xpar)))
  376.       {
  377. #ifdef DEBUG
  378.     DebugError("XpkRead: XpksUnpackChunk failed with %ld", xbuf->xb_Result);
  379. #endif
  380.     return xbuf->xb_Result;
  381.       }
  382.  
  383.       CopyMem((STRPTR) xpar->xsp_InBuf + rclen, lochdr, lochdrsize);
  384.     }
  385.     else
  386.       return (xbuf->xb_Result = XPKERR_CORRUPTPKD);
  387.  
  388.     updatefib(xbuf);
  389.     return ulen;
  390.  
  391.     /********************* Unpack powerpacked file ****************/
  392.   case XPKMODE_UPPP:
  393.     {
  394. #ifdef USE_POWERPACKER
  395.       struct Library *PPBase = xbuf->xb_SubBase;
  396.       STRPTR inbuf, inbufend;
  397.  
  398.       if(!(inbuf = (STRPTR) hookread (xbuf, XIO_READ, NULL, xbuf->xb_InLen - 4)))
  399.         return xbuf->xb_Result;
  400.       inbufend = inbuf + xbuf->xb_InLen - 4;
  401.  
  402.       ppDecrunchBuffer(inbufend, buf, (ULONG *) inbuf, DECR_NONE);
  403.  
  404.       xbuf->xb_Fib.xf_CCur = xbuf->xb_InLen;
  405.       xbuf->xb_Fib.xf_UCur = xbuf->xb_Fib.xf_ULen;
  406.       xbuf->xb_Fib.xf_NLen = 0;
  407.       xbuf->xb_Flags |= XMF_EOF;
  408.  
  409.       return (LONG) xbuf->xb_ULen;
  410. #else
  411.       return (xbuf->xb_Result = XPKERR_NOFUNC);
  412. #endif /* USE_POWERPACKER */
  413.     }
  414.  
  415.     /********************* Unpack unpacked file *******************/
  416.   case XPKMODE_UPUP:
  417.     {
  418.       ULONG len = xbuf->xb_Fib.xf_ULen - xbuf->xb_Fib.xf_CCur;
  419.  
  420.       if(len > CHUNKSIZE)
  421.         len = CHUNKSIZE;
  422.       else
  423.         xbuf->xb_Flags |= XMF_EOF;
  424.  
  425. // maxon_buf later should be removed
  426.       if(!(maxon_bug = (ULONG)hookread(xbuf, XIO_READ, buf, len)))
  427.         return xbuf->xb_Result;
  428.  
  429.       xbuf->xb_Fib.xf_CCur += len;
  430.       xbuf->xb_Fib.xf_UCur += len;
  431.       xbuf->xb_Fib.xf_NLen = Min(xbuf->xb_InLen - xbuf->xb_Fib.xf_UCur, CHUNKSIZE) + XPK_MARGIN;
  432.  
  433.       return (LONG) len;
  434.     }
  435.   }
  436.  
  437.   return xbuf->xb_Result;
  438. }
  439.  
  440. /**************************************************************************
  441.  *
  442.  *   XpkWrite() - write a chunk to a compressed file
  443.  *
  444.  */
  445.  
  446. #ifdef __cplusplus
  447.   extern "C"
  448. #endif
  449.  
  450. LONG __asm XpkWrite(register __a0 struct XpkBuffer *xbuf,
  451.     register __a1 STRPTR buf, register __d0 ULONG ulen)
  452. {
  453.   struct Library *XpkSubBase = xbuf->xb_SubBase;
  454.   struct XpkSubParams *xpar;
  455.   struct Headers *head = &xbuf->xb_Headers;
  456.   LONG clen, rclen, outbuflen;
  457.   UBYTE type;
  458.   STRPTR outbuf;
  459.   ULONG maxon_bug; //remove later after correction of bug
  460.  
  461.   if(!xbuf->xb_FirstChunk)
  462.     xbuf->xb_FirstChunk = ulen;
  463.   if(ulen > xbuf->xb_FirstChunk)
  464.     return (xbuf->xb_Result = XPKERR_BADPARAMS);
  465.  
  466.   /******************* Write the GlobHdr ********************/
  467.   if(!(xbuf->xb_Flags & XMF_GLOBHDR))
  468.   {
  469.     if(!xbuf->xb_Password)
  470.       CopyMem(buf, head->h_Glob.xsh_Initial, Min(16, ulen));
  471.     xbuf->xb_Flags |= XMF_GLOBHDR;
  472. // maxon_bug later should be removed
  473.     if(!(maxon_bug = (ULONG) hookwrite(xbuf, XIO_WRITE, &head->h_Glob,
  474.     sizeof(struct XpkStreamHeader))))
  475.       return xbuf->xb_Result;
  476.     xbuf->xb_Fib.xf_CCur += sizeof(struct XpkStreamHeader);
  477.   }
  478.  
  479.   /******************* Allocate the buffer *****************/
  480.   outbuflen = (ulen + ulen / 32 & ~3) + XPK_MARGIN;
  481.   if(!(outbuf = (STRPTR) hookwrite (xbuf, XIO_GETBUF, NULL, outbuflen)))
  482.     return xbuf->xb_Result;
  483.   outbuf += head->h_LocSize; /* compress to behind local header. */
  484.  
  485.   if(ulen < xbuf->xb_MinChunk)
  486.     goto copychunk;
  487.  
  488.   /******************* Pack the chunk **********************/
  489.   xpar = &xbuf->xb_PackParam;
  490.   xpar->xsp_InBuf = buf;
  491.   xpar->xsp_InLen = ulen;
  492.   xpar->xsp_OutBuf = outbuf;
  493.   xpar->xsp_OutBufLen = outbuflen - head->h_LocSize;
  494.   xpar->xsp_Number += 1;
  495.   xpar->xsp_Mode = xbuf->xb_PackingMode;
  496.   xpar->xsp_Password = xbuf->xb_Password;
  497.   xpar->xsp_LibVersion = xbuf->xb_SubInfo->xi_LibVersion;
  498.  
  499.   xbuf->xb_Result = XpksPackChunk(xpar);
  500.   xbuf->xb_Flags |= XMF_INITED;
  501.  
  502.   type = XPKCHUNK_PACKED;
  503.   clen = xpar->xsp_OutLen;
  504.  
  505.   if(xbuf->xb_Result == XPKERR_EXPANSION)
  506.   {
  507.     xbuf->xb_Result = 0;
  508. copychunk:
  509.     type = XPKCHUNK_RAW;
  510.     clen = ulen;
  511.     outbuf = buf;
  512.   }
  513.  
  514.   if(xbuf->xb_Result)
  515.     return xbuf->xb_Result;
  516.  
  517.   /******************* Write the chunk **********************/
  518.   head->h_Loc.xch_Word.xchw_Type = type;
  519.   if(head->h_Glob.xsh_Flags & XPKSTREAMF_LONGHEADERS)
  520.   {
  521.     head->h_Loc.xch_Long.xchl_ULen = ulen;
  522.     head->h_Loc.xch_Long.xchl_CLen = clen;
  523.   }
  524.   else
  525.   {
  526.     head->h_Loc.xch_Word.xchw_ULen = (WORD) ulen;
  527.     head->h_Loc.xch_Word.xchw_CLen = (WORD) clen;
  528.   }
  529.  
  530.   /* zeropad upto next longword */
  531.   for(rclen = clen; rclen & 3; ++rclen) outbuf[rclen] = 0;  
  532.  
  533.   head->h_Loc.xch_Word.xchw_CChk = cchecksum ((ULONG *) outbuf, rclen / 4);
  534.   head->h_Loc.xch_Word.xchw_HChk = 0;
  535.   head->h_Loc.xch_Word.xchw_HChk = hchecksum ((STRPTR) &head->h_Loc, head->h_LocSize);
  536.  
  537. // maxon_bug later should be removed
  538.   if(!(maxon_bug = (ULONG) hookwrite(xbuf, XIO_WRITE, &head->h_Loc, head->h_LocSize)))
  539.     return xbuf->xb_Result;
  540. // remove
  541.   if(!(maxon_bug = (ULONG) hookwrite (xbuf, XIO_WRITE, outbuf, rclen)))
  542.     return xbuf->xb_Result;
  543.  
  544.   head->h_Glob.xsh_ULen += ulen;
  545.   
  546.   xbuf->xb_Fib.xf_UCur += ulen;
  547.   xbuf->xb_Fib.xf_CCur += head->h_LocSize + rclen;
  548.   xbuf->xb_Fib.xf_NLen = Min(max(xbuf->xb_InLen, head->h_Glob.xsh_ULen) -
  549.     xbuf->xb_Fib.xf_UCur, (LONG) xbuf->xb_ChunkSize);
  550.  
  551.   return xbuf->xb_Result;
  552. }
  553.  
  554. /**************************************************************************
  555.  *
  556.  *   XpkSeek() - move around on a compressed file
  557.  *
  558.  */
  559.  
  560. #ifdef __cplusplus
  561.   extern "C"
  562. #endif
  563.  
  564. LONG __asm XpkSeek(register __a0 struct XpkBuffer *xbuf,
  565.     register __d0 LONG dist, register __d1 LONG mode)
  566. {
  567.   xbuf->xb_Result = XPKERR_NOFUNC;
  568.   parsegettags(xbuf);
  569.  
  570.   return xbuf->xb_Result;
  571. }
  572.  
  573. /**************************************************************************
  574.  *
  575.  *   XpkClose() - finish (de)compressing an XPK file
  576.  *
  577.  */
  578.  
  579. #ifdef __cplusplus
  580.   extern "C"
  581. #endif
  582.  
  583. LONG __asm XpkClose(register __a0 struct XpkBuffer *xbuf)
  584. {
  585.   struct Library *XpkSubBase = xbuf->xb_SubBase;
  586.   struct Headers *head = &xbuf->xb_Headers;
  587.   LONG outlen;
  588.  
  589.   if(!xbuf)
  590.     return 0;
  591.  
  592. #ifdef DEBUG
  593.   if(xbuf->xb_Result)
  594.     DebugError("XpkClose: failed (%ld) before XpkClose", xbuf->xb_Result);
  595. #endif
  596.  
  597.   switch(xbuf->xb_Format)
  598.   {
  599.   case XPKMODE_UPSTD:
  600.     if(xbuf->xb_Flags & XMF_INITED)
  601.       XpksUnpackFree (&xbuf->xb_PackParam);
  602.  
  603.   case XPKMODE_UPPP:
  604.     break;
  605.  
  606.   case XPKMODE_PKSTD:
  607.     if(!xbuf->xb_Result && !(xbuf->xb_Flags & XMF_GLOBHDR))
  608.     {
  609.       hookwrite (xbuf, XIO_WRITE, &head->h_Glob, sizeof(struct XpkStreamHeader));
  610. #ifdef DEBUG
  611.       if(xbuf->xb_Result)
  612.         DebugError("XpkClose: failed to write globhdr");
  613. #endif
  614.       xbuf->xb_Fib.xf_CCur += sizeof(struct XpkStreamHeader);
  615.     }
  616.  
  617.     if(!xbuf->xb_Result)
  618.     {
  619.       /******************* Write final chunk header *****************/
  620.       memset(&head->h_Loc, 0, head->h_LocSize);
  621.       head->h_Loc.xch_Word.xchw_Type = XPKCHUNK_END;
  622.       head->h_Loc.xch_Word.xchw_HChk = 0;
  623.       head->h_Loc.xch_Word.xchw_HChk =
  624.         hchecksum((STRPTR) &head->h_Loc, head->h_LocSize);
  625.       hookwrite (xbuf, XIO_WRITE, &head->h_Loc, head->h_LocSize);
  626. #ifdef DEBUG
  627.       if(xbuf->xb_Result)
  628.         DebugError("XpkClose: failed to write lochdr");
  629. #endif
  630.       xbuf->xb_Fib.xf_CCur += head->h_LocSize;
  631.       outlen = xbuf->xb_Fib.xf_CCur;
  632.  
  633.       /********************** Write global header *******************/
  634.       hookwrite (xbuf, XIO_SEEK, NULL, -outlen);
  635. #ifdef DEBUG
  636.       if(xbuf->xb_Result)
  637.         DebugError("XpkClose: failed to reset output");
  638. #endif
  639.  
  640.       head->h_Glob.xsh_Pack = XPK_COOKIE;
  641.       head->h_Glob.xsh_CLen = outlen - 8;
  642.       head->h_Glob.xsh_HChk = 0;
  643.       head->h_Glob.xsh_HChk =
  644.         hchecksum ((STRPTR) &head->h_Glob, sizeof(struct XpkStreamHeader));
  645.       hookwrite(xbuf, XIO_WRITE, &head->h_Glob, sizeof(struct XpkStreamHeader));
  646. #ifdef DEBUG
  647.       if(xbuf->xb_Result)
  648.         DebugError("XpkClose: failed updating globalhdr");
  649. #endif
  650.       hookwrite(xbuf, XIO_SEEK, 0, outlen - sizeof(struct XpkStreamHeader));
  651. #ifdef DEBUG
  652.       if(xbuf->xb_Result)
  653.         DebugError("XpkClose: failed to SEEK to end of output");
  654. #endif
  655.  
  656.       xbuf->xb_Fib.xf_CLen = xbuf->xb_Fib.xf_CCur;
  657.       xbuf->xb_Fib.xf_ULen = xbuf->xb_Fib.xf_UCur;
  658.     }
  659.  
  660.     /*************************** Shut down *************************/
  661.     if(xbuf->xb_Flags & XMF_INITED)
  662.       XpksPackFree(&xbuf->xb_PackParam);
  663.   }
  664.  
  665.   hookread(xbuf, xbuf->xb_Result ? XIO_ABORT : XIO_FREE, NULL, 0);
  666. #ifdef DEBUG
  667.   if(xbuf->xb_Result)
  668.     DebugError("XpkClose: failed read ABORT/FREE");
  669. #endif
  670.   hookwrite(xbuf, xbuf->xb_Result ? XIO_ABORT : XIO_FREE, NULL, 0);
  671. #ifdef DEBUG
  672.   if(xbuf->xb_Result)
  673.     DebugError("XpkClose: failed write ABORT/FREE");
  674. #endif
  675.  
  676.   if(xbuf->xb_Result && xbuf->xb_Result != XPKERR_CHECKSUM && xbuf->xb_OutName)
  677.     DeleteFile(xbuf->xb_OutName);
  678.  
  679.   parsegettags(xbuf);        /* Send information to the user */
  680.  
  681. #ifdef DEBUG
  682.   if(xbuf->xb_Result)
  683.     DebugError("XpkClose: failed freebufs?");
  684. #endif
  685.   return freebufs(xbuf);
  686. }
  687.  
  688. #endif /* XPKMASTER_XPKMASTER_C */
  689.  
  690.